/**************************************************************************//**
 * @item     CosyOS Kernel
 * @file     usv_loc.h
 * @brief    Service for User Task is to be executed locally
 * @author   迟凯峰
 * @version  V2.3.0
 * @date     2023.04.25
 ******************************************************************************/

#ifndef __USV_LOC_H
#define __USV_LOC_H

extern void __enter_critical(void);
extern bool __enter_critical_r(void);
extern void __exit_critical(void);

extern void __start_task  (tspTaskHandle task_hand, u8 state);
extern void __resume_task (tspTaskNode task_node);
extern void __suspend_task(tspTaskNode task_node);
extern void __delete_task (tspTaskNode task_node);
extern void __ressus_task (tspTaskNode task_node);
extern void __set_priority(tspTaskNode task_node, u8 tpl);

extern void __delay       (tDelay tc);
extern void __free_mut    (tspMut p);
extern bool __take_mut    (tspMut p, tDelay tc);
extern bool __take_bin    (volatile bool *p, tDelay tc, u8 type);
extern bool __take_sem    (tspSem p, tDelay tc);

extern bool  __recv_dm   (tDM *m0_, tDM *m1, size_t size, tDelay tc) __REENTRANT__;
extern bool  __recv_mail (void *lm, void *gm, size_t size, volatile bool *gf, tDelay tc) __REENTRANT__;
extern void *__recv_msg  (tspMsgQueue msg_queue, tDelay tc);
extern bool  __send_msg  (tspMsgQueue msg_queue, void *msg);
extern bool  __query_grp (volatile void *p, u8 size);
extern bool  __wait_grp  (volatile void *p, u8 size, tDelay tc);

extern void _MALLOC_MEM_ *__umalloc      (size_t size);
extern void _MALLOC_MEM_ *__ucalloc      (size_t nmemb, size_t size);
extern void _MALLOC_MEM_ *__urealloc     (void _MALLOC_MEM_ *p, size_t size);
extern void               __ufree        (void _MALLOC_MEM_ *p);
extern bool               __uinit_mempool(tsThrmem *p, size_t size);
extern void _MALLOC_MEM_ *__utalloc      (tsThrmem *p, size_t size);



/*
 * 任务
 */

/* 启动任务 */
#define sUSV_StartTask(thdl, state)	\
do{	\
	__enter_critical();	\
	__start_task(thdl, !state ? __READY__ : __SUSPENDED__);	\
}while(false)

/* 恢复任务 */
#define	sUSV_ResumeTask(node)	\
do{	\
	__enter_critical();	\
	__resume_task(node);	\
}while(false)

/* 挂起任务 */
#define	sUSV_SuspendTask(node)	\
do{	\
	__enter_critical();	\
	__suspend_task(node);	\
}while(false)

/* 删除任务 */
#define	sUSV_DeleteTask(node)	\
do{	\
	__enter_critical();	\
	__delete_task(node);	\
}while(false)

/* 恢复指定任务并挂起当前任务 */
#define	sUSV_ResSusTask(node)	\
do{	\
	__enter_critical();	\
	__ressus_task(node);	\
}while(false)

/* 设置任务优先级 */
#define	sUSV_SetPriority(node, tpl)	\
do{	\
	__enter_critical();	\
	__set_priority(node, tpl);	\
}while(false)



/*
 * 二值信号量
 */

/* 等待 */
#define	sUSV_WaitBin(bin, tc)	\
(	\
	__enter_critical_r() ? __take_bin(&bin, tc, __BINARY_WAIT__) : false	\
)

/* 获取 */
#define	sUSV_TakeBin(bin, tc)	\
(	\
	__enter_critical_r() ? __take_bin(&bin, tc, __BINARY_TAKE__) : false	\
)



/*
 * 互斥信号量
 */

/* 获取 */
#define	sUSV_TakeMut(mut, tc)	\
(	\
	__enter_critical_r() ? __take_mut(&mut, tc) : false	\
)

/* 释放 */
#define sUSV_FreeMut(mut)	\
do{	\
	__enter_critical();	\
	__free_mut(&mut);	\
}while(false)



/*
 * 计数信号量
 */

/* 获取 */
#define sUSV_TakeSem(sem, tc)	\
(	\
	__enter_critical_r() ? __take_sem(&sem, tc) : false	\
)

/* 释放 */
#define sUSV_FreeSem(sem)	\
do{	\
	__enter_critical();	\
	if(sem.counter < sem.max) sem.counter++;	\
	__exit_critical();	\
}while(false)



/*
 * 延时
 */

/* 延时 */
#define	sUSV_Delay(tc)	\
do{	\
	__enter_critical();	\
	__delay(tc);	\
}while(false)



/*
 * 定时
 */

/* 定时中断 */
#define	sUSV_TimInt(tmid, tc)	\
do{	\
	__enter_critical();	\
	vTIMINT_STMR[tmid] = vTIMINT_BUFF[tmid] = tc;	\
	__exit_critical();	\
}while(false)

/* 定时查询 */
#define	sUSV_TimQry(tmid, tc)	\
do{	\
	__enter_critical();	\
	vTIMQRY_STMR[tmid] = vTIMQRY_BUFF[tmid] = tc;	\
	__exit_critical();	\
}while(false)



/*
 * 进程内存
 */

/* malloc */
#define	sUSV_Malloc(size)	\
(	\
	__enter_critical_r() ? __umalloc(size) : NULL	\
)

/* calloc */
#define	sUSV_Calloc(nmemb, size)	\
(	\
	__enter_critical_r() ? __ucalloc(nmemb, size) : NULL	\
)

/* realloc */
#define	sUSV_Realloc(p, size)	\
(	\
	__enter_critical_r() ? __urealloc(p, size) : NULL	\
)

/* free */
#define	sUSV_Free(p)	\
do{	\
	__enter_critical();	\
	__ufree(p);	\
}while(false)



/*
 * 线程内存
 */

/* 初始化线程内存池 */
#define	sUSV_InitMempool(size)	\
(	\
	__enter_critical_r() ? __uinit_mempool(&thrmem, size) : false	\
)

/* 线程内存分配 */
#define	sUSV_Talloc(size)	\
(	\
	__enter_critical_r() ? __utalloc(&thrmem, size) : NULL	\
)

/* 释放线程内存池 */
#define	sUSV_FreeMempool	\
do{	\
	if(thrmem.p1 == NULL) break;	\
	sUSV_Free(thrmem.p1);	\
	thrmem.p1 = thrmem.p2 = NULL;	\
}while(false)



/*
 * 私信
 */

/* 接收私信 */
#define	sUSV_RecvDM(tc)	\
(	\
	__enter_critical_r() ? __recv_dm(&m0_, &m0 + 1, __DM_SIZE__, tc) : false	\
)

/* 发送私信 */
#if SYSCFG_COMPILEMODE == __C89__
	#define	sUSV_SendDM(task)	\
		__enter_critical();	\
		vSendDM_f = true;	\
		__DM_PSP__;	\
		while(true)	\
		if(!vSendDM_f)	\
		{	\
			__exit_critical();	\
			break;	\
		}	\
		else task(__DM_VAL__, 
#elif SYSCFG_COMPILEMODE == __C99__
	#define sUSV_SendDM(task, ...)	\
	do{	\
		__enter_critical();	\
		vSendDM_f = true;	\
		__DM_PSP__;	\
		task(__DM_VAL__, __VA_ARGS__);	\
		__exit_critical();	\
	}while(false)
#endif



/*
 * 全局变量
 */

/* 读全局变量 */
#define sUSV_ReadGVar(gv)	\
(	\
	__enter_critical_r() ? gv : gv	\
);	\
__exit_critical()

/* 读全局数组 */
#define sUSV_ReadGAry(lp, gp, size)	\
do{	\
	__enter_critical();	\
	__memcpy(lp, gp, size);	\
	__exit_critical();	\
}while(false)

/* 读全局字符串 */
#define sUSV_ReadGStr(ls, gs)	\
do{	\
	__enter_critical();	\
	__strcpy(ls, gs);	\
	__exit_critical();	\
}while(false)

/* 写全局变量 */
#define sUSV_WriteGVar(gp, lp, size)	\
do{	\
	static tsVarNode _SV_MEM_ var_node = {gp, NULL, size};	\
	var_node.lvar = lp;	\
	__enter_critical();	\
	sWRITE_VAR_WRITE(&var_node);	\
	size ? __memcpy(gp, lp, size) : __strcpy((char *)gp, (char *)lp);	\
	sWRITE_VAR_WRITE(NULL);	\
	__exit_critical();	\
}while(false)

/* 全局变量自运算 */
#define sUSV_SelfOpe(gv, type, fp)	\
do{	\
	static type lv;	\
	static tsVarNode _SV_MEM_ var_node = {&gv, &lv, sizeof(gv)};	\
	__enter_critical();	\
	lv = gv;	\
	sWRITE_VAR_WRITE(&var_node);	\
	(*fp)();	\
	sWRITE_VAR_WRITE(NULL);	\
	__exit_critical();	\
}while(false)



/*
 * 消息邮箱
 */

/* 接收邮件 */
#define sUSV_RecvMail(mail, mbox, tc)	\
(	\
	__enter_critical_r() ? __recv_mail(mail, &mbox, sizeof(mbox), &mbox##_gnmf, tc) : false	\
)

/* 发送邮件 */
#define sUSV_SendMail(mbox, mail)	\
do{	\
	static tsMbxNode _SV_MEM_ mbx_node = {&mbox, NULL, sizeof(mbox), &mbox##_gnmf, true};	\
	mbx_node.lmbx = mail;	\
	mbx_node.lnmf = true;	\
	__enter_critical();	\
	sWRITE_MBX_WRITE(&mbx_node);	\
	__memcpy(&mbox, mail, sizeof(mbox));	\
	sWRITE_MBX_WRITE(NULL);	\
	mbox##_gnmf = mbx_node.lnmf;	\
	__exit_critical();	\
}while(false)



/*
 * 消息队列
 */

/* 发送消息 */
#define	sUSV_SendMsg(que, msg)	\
(	\
	__enter_critical_r() ? __send_msg(que, msg) : false	\
)

/* 接收消息 */
#define	sUSV_RecvMsg(que, tc)	\
(	\
	__enter_critical_r() ? __recv_msg(que, tc) : NULL	\
)



/*
 * 事件标志组
 */

/* 查询标志组 */
#define	sUSV_QueryFlagGroup(group)	\
(	\
	__enter_critical_r() ? __query_grp(&group, sizeof(group)) : false	\
)

/* 等待标志组 */
#define	sUSV_WaitFlagGroup(group, tc)	\
(	\
	__enter_critical_r() ? __wait_grp(&group, sizeof(group), tc) : false	\
)

/* 清除标志组 */
#define sUSV_ClearFlagGroup(group)	\
do{	\
    __enter_critical();	\
	  sizeof(group) == 1 ? *(u8  *)&group = false	\
	: sizeof(group) == 2 ? *(u16 *)&group = false	\
	: sizeof(group) == 4 ? *(u32 *)&group = false	\
	: OS_NOPx1;	\
    __exit_critical();	\
}while(false)

/* 写标志位 */
#define sUSV_WriteFlagBit(group, bit, value)	\
do{	\
	__enter_critical();	\
	group.bit = value;	\
	__exit_critical();	\
}while(false)



#endif
